home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Utilities / Programming / EnterAct 3.5 / Drag_on Modules / hAWK programs / $MFS_SuperReplace < prev    next >
Encoding:
Text File  |  1993-04-09  |  7.0 KB  |  172 lines  |  [TEXT/KEEN]

  1. #$MFS_SuperReplace - replace all instances of a pattern of text in one
  2. #or more files, even if the pattern to find spans more than one line.
  3. # Use the "Set variables" button to at least set the text for the
  4. #"find" and "replace" variables - in the text for "find", use a single space to
  5. #separate the words, and also put two spaces wherever the string of text might
  6. #be broken to continue on the next line. More on this below. Some options are
  7. #available: document all changes to stdout, treat the "find" string as pure
  8. #text rather than a regular expression, ignore case while searching.
  9. #
  10. #Variables that you can set with "Set variables":
  11. #Variable        values, meaning, examples
  12. #--------        ----------------------------------------------
  13. #find            the string of text to find, eg find =MyFUnction
  14. #replace        the string of text to replace what's found, 
  15. #                    eg replace =MyFunction
  16. #document        0 means don't document the changes, non -0 means print list
  17. #                    of file names and lines where changes were made, to stdout
  18. #                    And, it prints the original version before the change.
  19. #regex            non-0 means your "find" string is a regular expression, and you should
  20. #                    escape special characters as noted below. A 0 value means
  21. #                    your "find" string is intended as a pure text string and all
  22. #                    characters in the string should be interpreted literally.
  23. #ignorecase        0 means don't ignore the case when searching, non-0 means treat
  24. #                    'a' and 'A' the same, etc.
  25. #-the default values are:
  26. #    document =1 (document changes to stdout)
  27. #    regex =1 (treat the "find" string as a regular expression)
  28. #ignorecase =0  (be sensitive to upper and lower case)
  29. #-don't put a space between the '=' and the value unless you want the space
  30. #to be part of the value. No quotes should be used around values, whether
  31. #string or number.            
  32. #
  33. #PLEASE NOTE if your "find" string is a regular expression (regex =1),
  34. #then characters which have special meaning when interpreted within a
  35. #regular expression should be ESCAPED if you want to match the literal character
  36. #- these are     \^$.[]|()*+?     . For example, to find
  37. #    "MyFunc(s.member) + a[0]" set the "find" variable to
  38. #    find=MyFunc\(s\.member\) \+ a\[0\]
  39. #If your "find" string is not a regular expression (regex =0),
  40. #then escapes for special punctuation will be inserted for you, except for
  41. #the escaping backslash "\" itself. In addition, you will need to use a backslash
  42. #to match an escape sequence, such as "\t" for a tab, or "\b" for word boundary.
  43. #For example, the "MyFunc" find string with regex =0 would be
  44. #    find =MyFunc(s.member) + a[0]
  45. #
  46. #If you're not familiar with regular expressions yet, set regex to 0 and just
  47. #search for pure text until you feel ready to give \^$.[]|()*+? \1\> etc a try.
  48. #
  49. #NOTE in your replace string, a '&' or any of '\1' through '\9' will retain
  50. #their special meaning (& == all of what was matched, \1 == first tagged group etc)
  51. #regardless of the value of '"regex", though it’s not possible to tag groups
  52. #unless you set regex=1.
  53. #
  54. #For finding purposes, each single space in the "find" string
  55. #is converted to the regular-expression equivalent of
  56. #    "at least one space, tab, or return". If some of the white space is
  57. #entirely optional, use two spaces - this produces
  58. #the equivalent of "zero or more spaces, tabs, or returns" for each pair of spaces
  59. #in the find pattern. Seemingly backwards, I know, but most space is of the
  60. #"one or more" kind rather than the "zero or more" kind.
  61.  
  62. #Typically use the "MFS selected files" option after selecting the files
  63. #for multi–file operations within the calling application.
  64.  
  65. #This program progressively adds input lines to the end of the variable "multi",
  66. #does the replacement, and then subtracts lines from the beginning of "multi",
  67. #storing them in the array "out[]". At the end of an input file, the entire
  68. #file is rewritten from out[] and multi.
  69. #Rewriting files with hAWK has the following side-effects:
  70. #- the file creator will change to '????', though no resources will be
  71. #    lost.
  72. #- THINK C, EnterAct, etc projects will not be aware of the changes, so you
  73. #    should select the "Update From Disk" command later to bring your project
  74. #    up to date.
  75. #- marker locations will be thrown off. If you placed the markers using
  76. #    EnterAct's "Automark" command, you can replace them with the same
  77. #    command fairly painlessly.
  78. #
  79. #Sequence:
  80. #--Modify the find string
  81. #--Create the "actual" program to run, by reading the "template" program
  82. #    and inserting the (static) strings to search for and use for replacement.
  83. #--Execute the new program with a "hAWK" call.
  84. #Note this is done entirely for speed: a static regular expression such as
  85. #    match($0, "struct")
  86. #is parsed only once, whereas a dynamic regular expression such as
  87. #    find = "struct"
  88. #    match($0, find)
  89. #is parsed each time the match (or sub or gsub) statement is executed.
  90. #
  91. #BUG, goofball whitespace such as an option-space or formfeed left to you as an exercise.
  92.  
  93. # User’s Manual references:
  94. # «hAWK User’s Manual» «F   Running hAWK programs»
  95. # «hAWK User’s Manual» «L  5   Regular expressions»
  96. # «hAWK User’s Manual» «M  5   Built-in string and file functions»
  97. # «hAWK User’s Manual» «K  4   Built-in variables»
  98. # «hAWK User’s Manual» «K  8   Arrays»
  99. # «hAWK User’s Manual» «N   User-defined functions»
  100. # «hAWK User’s Manual» «P  3   The getline function»
  101. # «hAWK User’s Manual» «O  3   Output into files»
  102. # «hAWK User’s Manual» «Q   The hAWK function»
  103.  
  104.  
  105. BEGIN {    maxLines = split(find, a) + 1;
  106.         if (document+0 != 0)
  107.             {
  108.             document = 1
  109.             printf("Searched for\n\t%s\n", find);
  110.             printf("and replaced with\n\t%s\n", replace);
  111.             num_files = ARGC-1
  112.             }
  113.         if (regex+0 == 0)
  114.             gsub(/([$^.[\]|()*+?])/,"\\\1", find);#escape special characters
  115.         gsub(/  /, "[ \\t\\n]*", find);#replace two blanks by optional whitespace
  116.         gsub(/([^[]) /, "\1[ \\t\\n]+", find);#replace one blank by at least one whitespace
  117.         
  118.         #Create specific replace program from MFS_SuperReplace.T
  119.         templateFile = STDPATH "Drag_on Modules:hAWK programs:" "MFS_SuperReplace.T"
  120.         actualFile = STDPATH "Drag_on Modules:hAWK programs:" "MFS_SuperReplace.A"
  121.         while (getline < templateFile > 0)
  122.             {
  123.             if (match($0, /##MARK/))
  124.                 {
  125.                 ++tLines
  126.                 if (match($0, /##MARK find/))
  127.                     {
  128.                     $0 = "\t\twhile (match(multi, /" find "/) > 0)"
  129.                     }
  130.                 else if (match($0, /##MARK repToo/))
  131.                     {
  132.                     $0 = "\t\t\tsub(/" find "/, \"" replace "\", multi);"
  133.                     }
  134.                 else if (match($0, /##MARK maxLines/))
  135.                     sub(/maxLines/, maxLines)
  136.                 else
  137.                     {
  138.                     print "Unknown ##MARK:"
  139.                     print $0
  140.                     exit
  141.                     }
  142.                 }
  143.             print > actualFile
  144.             }
  145.         if (tLines < 3)#template missing or damaged
  146.             {
  147.             print "The template file"
  148.             print templateFile
  149.             if (!tLines)
  150.                 print "is missing."
  151.             else
  152.                 print "is damaged."
  153.             exit
  154.             }
  155.         else
  156.             {
  157.             close(templateFile)
  158.             close(actualFile)
  159.             }
  160.         #Execute the new specific program MFS_SuperReplace.A
  161.         argv[x++] = "hAWK"
  162.         argv[x++] = "-f" actualFile
  163.         argv[x++] = "-v" "ignorecase=" ignorecase
  164.         argv[x++] = "-v" "document=" document
  165.         if (document != 0)
  166.             argv[x++] = "-v" "num_files=" num_files
  167.         argv[x++] = "--"
  168.         for (i = 1; i < ARGC; ++i)
  169.             argv[x++] = ARGV[i]
  170.         hAWK(argv);    #execution transfers to MFS_SuperReplace.A
  171.         }
  172.